/**
 * 权限声明：
 */
package com.handy.webwork;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.handy.webwork.action.ActionMapping;
import com.handy.webwork.config.ConfigurationManager;
import com.handy.webwork.config.HandyConfiguration;
import com.handy.webwork.plugin.PluginNotifier;
import com.handy.webwork.view.FreemarkerTemplateFactory;

/**
 * 业务请求分发器。
 * 
 * @author rocken.zeng@gmail.com
 * 
 */
public class FilterDispatcher implements Filter {
	private static Log log = LogFactory.getLog(FilterDispatcher.class);
	ConfigurationManager configurationManager = new ConfigurationManager();
	private FilterConfig filterConfig;

	public void destroy() {
		PluginNotifier.destroy();
		configurationManager.removeAll();
	}

	@SuppressWarnings("unchecked")
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		ServletContext servletContext = getServletContext();

		request.setCharacterEncoding(HandyConfiguration
				.properties(HandyConfiguration.PROP_ENCODING));// 设置字符编码

		if (log.isDebugEnabled()) {
			log.debug("ContentType:" + req.getContentType());
			// 页面参数传递
			Map formMap = req.getParameterMap();
			log.debug("param count:" + formMap.size());
			// 打印参数
			String url = request.getRequestURL().toString();
			log.debug(url);
			Set<Entry> params = formMap.entrySet();
			log.debug("page parameter : ");
			for (Map.Entry entry : params) {
				Object[] values = (Object[]) entry.getValue();
				for (Object s : values) {
					log.debug(entry.getKey() + " = " + s);
				}
			}
		}
		// 判断是否有用户请求的控制器。
		ActionMapping actionMapping = findActionMapping(request);
		if (null == actionMapping) {
			if (log.isDebugEnabled()) {
				log.debug("actionMapping is null");
			}
			chain.doFilter(request, response);
			return;
		}
		// 分发
		Dispatcher dispatcher = new Dispatcher(request, response,
				servletContext, actionMapping);
		dispatcher.invok();
	}

	/**
	 * 初始化：
	 * 1.载入配置文件；
	 * 2.创建freemarker模板工厂；
	 * 3.启动插件。
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
//		log.info("webwork init");
		configurationManager.loadConfiguration();// 载入配置文件
		configurationManager.loadRootPath(getServletContext().getRealPath("/"));
		FreemarkerTemplateFactory.getInstance().init(
				filterConfig.getServletContext());// 创建freemarker模板工厂
		//启动插件
		PluginNotifier.run();
	}

	protected ServletContext getServletContext() {
		return filterConfig.getServletContext();
	}
	
	/**
	 * 查找用户请求的action <br>
	 * 
	 * @param request
	 * @return
	 */
	private ActionMapping findActionMapping(HttpServletRequest request) {
		// 分析requestURL
		String requestURL = request.getRequestURL().toString();
		String contextPath = request.getContextPath();//当站点为root时该值为空
		String serviceName = "";
		String requestURI = request.getRequestURI();
		
		if (contextPath != null && !"".equals(contextPath)){
			serviceName = requestURI.substring(requestURI
					.indexOf(contextPath)
					+ contextPath.length() + 1, requestURI.lastIndexOf('.'));
		}else{
			serviceName = requestURI.substring(1,requestURI.lastIndexOf('.'));
		}
		
		String sServiceName = requestURI.substring(requestURI.lastIndexOf('/')+1,requestURI.lastIndexOf('.'));
		
		
		if (log.isDebugEnabled()) {
			log.debug("requestURL : " + requestURL);
			log.debug("requestURI : " + requestURI);
			log.debug("contextPath : " + contextPath);
			log.debug("serviceName : " + serviceName);
			log.debug("sServiceName : " + sServiceName);
		}
		// 检索对应控制器
		ActionMapping actionMapping = null;
		
		//先搜索带插件前缀的action
		actionMapping = HandyConfiguration.actionMappings(
				serviceName.toUpperCase());
		//找不到则再搜索不带插件前缀的action
		if (null == actionMapping) {
			actionMapping = HandyConfiguration.actionMappings(sServiceName
					.toUpperCase());
			//如果该action是属于某插件，则提示访问错误
//			if (null != actionMapping && !"".equals(actionMapping.getPluginName()) && !"".equals(actionMapping.getPluginRoot())){
//				if (log.isErrorEnabled()){
//					log.info("请求的action["+requestURL+"]属于插件["+actionMapping.getPluginName()+"],访问链接必须加上["+actionMapping.getPluginRoot()+"]");
//				}
//				return null;
//			}
		}
		
		if (null == actionMapping) {
			if (log.isErrorEnabled()) {
				//log.warn("找不到请求对应的serviceName : " + serviceName);
				log.error("请求页面不存在[" + requestURL + "]");
			}
//			if (serviceName.indexOf('/') > -1) {
//				serviceName = serviceName.substring(serviceName
//						.lastIndexOf('/') + 1);				
//			}
//			if (log.isWarnEnabled()) {
//				log.warn("处理后的请求serviceName : " + serviceName);
//			}
//			actionMapping = HandyConfiguration.actionMappings(
//					serviceName.toUpperCase());
		}
		return actionMapping;
	}

}